﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BallsCtr : MonoBehaviour {
    public GameObject gm;
    public GameObject bg;
    public GameObject ballPrefab;
    public GameObject specialBallPrefab;
    public GameObject rotateBonusPrefab;

    public float activatedTime;

    float addTimer;
    public float addNeedTime;
    public int addBallsNumber;

    List<GameCtr.Ball> ballsList;

    public static class BallTag
    {
        public const int centerBallTag = 0;
        public const int startBallTag = 1;
        public const int ballTag = 2;
        public const int specialBallTag = 3;
        public const int rotateBonusTag = 4;
    }

    
    // Use this for initialization
    void Start () {
        ballsList = gm.GetComponent<GameCtr>().ballsList;
        GameStartBalls();

        addTimer = .0f;

        //Bonus test
        StartCoroutine(BonusCreate());
        StartCoroutine(SpecialCreate());
    }
	
	// Update is called once per frame
	void Update () {
        if (GameCtr.isPause)
        {            
            return;
        }
        GameAddBalls();
        ActivateBalls();
        GameMoveBalls();
	}

    bool InstantiateBall(Vector3 pos, float r, int tag)
    {
        foreach(GameCtr.Ball gb in ballsList)
        {
            if(Vector3.Distance(gb.ball.GetComponent<RectTransform>().anchoredPosition3D, pos) < gb.radius + r)
            {
                return false;
            }
        }

        GameObject go;

        if (tag == BallTag.rotateBonusTag)
        {
            go = Instantiate(rotateBonusPrefab, bg.transform);           
        }
        else if (tag == BallTag.ballTag || tag == BallTag.centerBallTag || tag == BallTag.startBallTag)
        {
            go = Instantiate(ballPrefab, bg.transform);
        }
        else if (tag == BallTag.specialBallTag)
        {
            go = Instantiate(specialBallPrefab, bg.transform);
        }
        else
        {
            Debug.Log("ball create error!");
            return false;
        }
        //go.transform.SetParent(bg.transform);
        RectTransform rect = go.GetComponent<RectTransform>();
        rect.anchoredPosition3D = pos;
        rect.sizeDelta = new Vector2(2 * r, 2 * r);
        if(tag == BallTag.centerBallTag)
        {
            go.GetComponent<Image>().color = new Color(0, 0, 0, 1);
        }
        else if(tag == BallTag.specialBallTag)
        {
            float deltaAngel = Vector3.Angle(Vector3.left, -pos);
            float y = rect.anchoredPosition3D.y;
            if (y <= 0)
            {
                rect.Rotate(0, 0, -deltaAngel);
            }
            else
            {
                rect.Rotate(0, 0, deltaAngel);
            }
        }
        

        GameCtr.Ball ball = new GameCtr.Ball();
        ball.ball = go;
        ball.radius = r;
        ball.tag = tag;
        ball.timer = .0f;
        ball.isActivated = false;
        ball.direction = Random.Range(-1, 2);
        ball.speed = Random.Range(20.0f, 50.0f);

        ballsList.Add(ball);

        return true;
    }

    bool GameStartBalls()
    {
        try
        {
            InstantiateBall(new Vector3(0, 0, 0), 103.0f, BallTag.centerBallTag);

            InstantiateBall(new Vector3(0, 157.0f, 0), 54.0f, BallTag.startBallTag);
            InstantiateBall(new Vector3(0, -157.0f, 0), 54.0f, BallTag.startBallTag);

            InstantiateBall(new Vector3(157.0f, 0, 0), 54.0f, BallTag.startBallTag);
            InstantiateBall(new Vector3(-157.0f, 0, 0), 54.0f, BallTag.startBallTag);

            InstantiateBall(new Vector3(111.5f, 111.5f, 0), 54.0f, BallTag.startBallTag);
            InstantiateBall(new Vector3(-111.5f, 111.5f, 0), 54.0f, BallTag.startBallTag);
            InstantiateBall(new Vector3(111.5f, -111.5f, 0), 54.0f, BallTag.startBallTag);
            InstantiateBall(new Vector3(-111.5f, -111.5f, 0), 54.0f, BallTag.startBallTag);

            //bonus test
            //InstantiateBall(new Vector3(200.0f, 200.0f, 0), 54.0f, 3);
        }
        catch
        {
            Debug.LogError("StartBalls error!");
            return false;
        }

        return true;
    }

    void ActivateBalls()
    {
        for(int i = 0; i < ballsList.Count; i++)
        {
            if(ballsList[i].isActivated == false && ballsList[i].tag != BallTag.centerBallTag)
            {
                GameCtr.Ball gb = ballsList[i];
                gb.timer += Time.deltaTime;
                Color oldColor = gb.ball.GetComponent<Image>().color;
                gb.ball.GetComponent<Image>().color = new Color(oldColor.r, oldColor.g, oldColor.b, gb.timer / activatedTime);
                ballsList[i] = gb;
            }
            if(ballsList[i].timer >= activatedTime)
            {
                GameCtr.Ball gb = ballsList[i];
                gb.isActivated = true;
                gb.timer = activatedTime;
                ballsList[i] = gb;
            }
        }
    }

    void RandomAddBall(int i, int tag = BallTag.ballTag)
    {
        for(int j = 0; j < i; )
        {
            float x = Random.Range(-500.0f, 500.0f);
            float y = Random.Range(-900.0f, 900.0f);
            float r = Random.Range(15.0f, 54.0f);
            Vector3 pos = new Vector3(x, y, 0);
    
            if(InstantiateBall(pos, r, tag) == false)
            {
                continue;
            }
            else
            {
                j++;
            }
        }
        
    }

    void GameAddBalls()
    {
        addTimer += Time.deltaTime;
        if(addTimer >= addNeedTime)
        {
            RandomAddBall(addBallsNumber);
            //RandomAddBall(1, BallTag.specialBallTag);
            addTimer = .0f;          
        }       
    }

    IEnumerator BonusCreate()
    {
        while (true) {
            yield return new WaitForSeconds(10.0f);
            RandomAddBall(1, BallTag.rotateBonusTag);
        }
        //StartCoroutine(BonusCreate());
    }

    IEnumerator SpecialCreate()
    {
        while (true)
        {
            yield return new WaitForSeconds(4.0f);
            RandomAddBall(1, BallTag.specialBallTag);
        }
    }

    void GameMoveBalls()
    {
        for(int i = 0; i < ballsList.Count; i++)
        {
            if(ballsList[i].tag != BallTag.ballTag)
            {
                continue;
            }

            RectTransform ballRT = ballsList[i].ball.GetComponent<RectTransform>();
            Vector3 direction = (Vector3.zero - ballRT.anchoredPosition3D).normalized * ballsList[i].direction * ballsList[i].speed;
            ballRT.anchoredPosition3D += direction * Time.deltaTime;

            if(Vector3.Distance(ballRT.anchoredPosition3D, Vector3.zero) <= 103.0f + ballsList[i].radius)
            {
                GameCtr.Ball temp = ballsList[i];
                temp.direction = - temp.direction;
                ballsList[i] = temp;
            }
        }
    }
}
